package util

import (
	"reflect"
)

type Mapper struct {
	from   reflect.Value
	fields []string
}

func MapFrom(from interface{}) Mapper {
	return Mapper{from: reflect.ValueOf(from)}
}

func (m Mapper) Take(fields ...string) Mapper {
	m.fields = fields
	return m
}

func (m Mapper) To(to interface{}) interface{} {
	var rtn interface{}
	if m.from.Kind() != reflect.Slice {
		v := reflect.New(reflect.TypeOf(to))
		for _, name := range m.fields {
			v.Elem().FieldByName(name).Set(m.from.FieldByName(name))
		}
		rtn = v.Interface()
	} else {
		list := make([]interface{}, m.from.Len())
		for i := 0; i < m.from.Len(); i++ {
			v := reflect.New(reflect.TypeOf(to))
			for _, name := range m.fields {
				v.Elem().FieldByName(name).Set(m.from.Index(i).FieldByName(name))
			}
			list[i] = v.Interface()
		}
		rtn = list
	}
	return rtn
}
